﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Netfraction.Network.Protocol.BASE.Factory
{
    public enum GETTypes : int
    {
        File = 0,
        List = 1
    }

    public enum GETParameterOptions : int
    {
        Type = 0,
        Identifier = 1,
        StartPosition = 2,
        BytesToReceive = 3,
        RecursiveList = 4
    }

    public class FactoryGET : ProtocolMessageFactory
    {
        public override ProtocolMessage Create(ProtocolMessage.MessageTypeEnum messageType, Dictionary<int, object> parameters)
        {
            ProtocolMessage proto = new ProtocolMessage(messageType, ProtocolFeatureBASE.FeatureActions.ActionGET);

            int type = (int)parameters[(int)GETParameterOptions.Type];
            string typeStr = string.Empty;
            if (GetTypeString(type, out typeStr))
            {
                proto.Parameters.Add(new ProtocolParameter(typeStr));
            }
            else
            {
                // call extension handlers
                // if (extensionResult != null)
                // {
                //  typeStr = extensionResult.ToString();
                //  if (typeStr != string.Empty)
                //  {
                //      proto.GETParameterOptions.Add(new ProtocolParameter(typeStr));
                //  }
                // }
            }

            // "Identifier must come from the namespace of the current session hash", so check that it does...
            string identifier = parameters[(int)GETParameterOptions.Identifier].ToString();
            proto.Parameters.Add(new ProtocolParameter(identifier));

            if (parameters.ContainsKey((int)GETParameterOptions.StartPosition))
            {
                proto.Parameters.Add(new ProtocolParameter(parameters[(int)GETParameterOptions.StartPosition].ToString()));
            }
            else
            {
                proto.Parameters.Add(new ProtocolParameter("0"));   // for example with a 'list' type, this is always zero
            }

            if (parameters.ContainsKey((int)GETParameterOptions.BytesToReceive))
            {
                proto.Parameters.Add(new ProtocolParameter(parameters[(int)GETParameterOptions.BytesToReceive].ToString()));
            }
            else
            {
                proto.Parameters.Add(new ProtocolParameter("-1"));  // <bytes> may be set to -1 to indicate that the sending client should fill 
                                                                    // it in with the number of bytes needed to complete the file from <start_pos>.
            }

            if (parameters.ContainsKey((int)GETParameterOptions.RecursiveList))
            {
                proto.Parameters.Add(new ProtocolParameter(GetParameterCodeForParameter(GETParameterOptions.RecursiveList), "1"));
            }

            return proto;
        }

        private static string GetParameterCodeForParameter(GETParameterOptions param)
        {
            switch (param)
            {
                case GETParameterOptions.RecursiveList:
                    return "RE";
                default:
                    return "";
            }
        }

        private static bool GetTypeString(int type, out string typeString)
        {
            if (Enum.IsDefined(typeof(GETTypes), type))
            {
                switch ((GETTypes)type)
                {
                    case GETTypes.File:
                        typeString = "file";
                        return true;
                    case GETTypes.List:
                        typeString = "list";
                        return true;
                    default:
                        break;
                }
            }
            typeString = string.Empty;
            return false;
        }
    }
}
